<?php
define('PHP_MAX_INT',2147483647);
define('PHP_MIN_INT',-2147483648);

/**
 * 游戏公共类库 v1.0.1
 */
class AppCommon
{
    static $_platform=array(1=>'安卓',3=>"苹果");
	/**
	 * 根据指定的键对数组排序
	 *
	 * 用法：
	 * @code php
	 * $rows = array(
	 *           array('id' => 1, 'value' => '1-1', 'parent' => 1),
	 *           array('id' => 2, 'value' => '2-1', 'parent' => 1),
	 *           array('id' => 3, 'value' => '3-1', 'parent' => 1),
	 *           array('id' => 4, 'value' => '4-1', 'parent' => 2),
	 *           array('id' => 5, 'value' => '5-1', 'parent' => 2),
	 *           array('id' => 6, 'value' => '6-1', 'parent' => 3),
	 * );
	 *
	 * $rows = Helper_Array::sortByCol($rows, 'id', SORT_DESC);
	 * dump($rows);
	 * // 输出结果为：
	 * // array(
	 * //         array('id' => 6, 'value' => '6-1', 'parent' => 3),
	 * //         array('id' => 5, 'value' => '5-1', 'parent' => 2),
	 * //         array('id' => 4, 'value' => '4-1', 'parent' => 2),
	 * //         array('id' => 3, 'value' => '3-1', 'parent' => 1),
	 * //         array('id' => 2, 'value' => '2-1', 'parent' => 1),
	 * //         array('id' => 1, 'value' => '1-1', 'parent' => 1),
	 * // )
	 * @endcode
	 *
	 * @param array $array 要排序的数组
	 * @param string $keyname 排序的键
	 * @param int $dir 排序方向
	 *
	 * @return array 排序后的数组
	 */
	static function sortByCol($array, $keyname, $dir = SORT_ASC)
	{
		return self::sortByMultiCols($array, array($keyname => $dir));
	}
	/**
	 * 将一个二维数组按照多个列进行排序，类似 SQL 语句中的 ORDER BY
	 *
	 * 用法：
	 * @code php
	 * $rows = Helper_Array::sortByMultiCols($rows, array(
	 *           'parent' => SORT_ASC,
	 *           'name' => SORT_DESC,
	 * ));
	 * @endcode
	 *
	 * @param array $rowset 要排序的数组
	 * @param array $args 排序的键
	 *
	 * @return array 排序后的数组
	 */
	static function sortByMultiCols($rowset, $args)
	{
		$sortArray = array();
		$sortRule = '';
		foreach ($args as $sortField => $sortDir)
		{
			foreach ($rowset as $offset => $row)
			{
				$sortArray[$sortField][$offset] = $row[$sortField];
			}
			$sortRule .= '$sortArray[\'' . $sortField . '\'], ' . $sortDir . ', ';
		}
		if (empty($sortArray) || empty($sortRule)) {
			return $rowset;
		}
		eval('array_multisort(' . $sortRule . '$rowset);');
		return $rowset;
	}

	/**
	 * 判断手机号是否正确
	 * @param string $str
	 * @return number
	 */
	public static function is_mobile($str){
		return preg_match("/^((\(\d{3}\))|(\d{3}\-))?13\d{9}$/", $str);
	}

	/**
	 * 缓存管理
	 * @param mixed $name 缓存名称，如果为数组表示进行缓存设置 无Redis情况下可以使用此方法
	 * @param mixed $value 缓存值
	 * @param mixed $options 缓存参数 int类型则表示缓存时间
	 * @return mixed
	 * @author ChenZhiYin
	 * @version 1.0.0 2014-10-20
	 */
	public static function FileCache($name,$value='',$options=null) {
		static $cache   =   '';
		if(is_array($options) && empty($cache)){
			// 缓存操作的同时初始化
			$type       =   isset($options['type'])?$options['type']:'';
			$cache      =   CacheFile::getInstance($options);
		}elseif(is_array($name)) { // 缓存初始化
			$type       =   isset($name['type'])?$name['type']:'';
			$cache      =   CacheFile::getInstance($name);
			return $cache;
		}elseif(empty($cache)) { // 自动初始化
			$cache      =   CacheFile::getInstance();
		}
		if(''=== $value){ // 获取缓存
			return $cache->get($name);
		}elseif(is_null($value)) { // 删除缓存
			return $cache->rm($name);
		}else { // 缓存数据
			if(is_array($options)) {
				$expire     =   isset($options['expire'])?$options['expire']:NULL;
			}else{
				$expire     =   is_numeric($options)?$options:NULL;
			}
			return $cache->set($name, $value, $expire);
		}
	}

	/**
	 * 文件缓存, 快速文件数据读取和保存 针对简单类型数据 字符串、数组
	 * @param string $name 缓存名称
	 * @param mixed $value 缓存值
	 * @param string $path 缓存路径
	 * @return mixed
	 * @author ChenZhiYin
	 * @version 1.0.0 2014-10-20
	 */
	public static function FastCache($name, $value='', $path='') {
		if (empty($path)){
			$path=KG_APP_ROOT.'/data/cache/';
		}
		static $_cache  = array();
		$filename       = $path . $name . '.php';
		if ('' !== $value) {
			if (is_null($value)) {
				// 删除缓存
				return false !== strpos($name,'*')?array_map("unlink", glob($filename)):unlink($filename);
			} else {
				// 缓存数据
				$dir            =   dirname($filename);
				// 目录不存在则创建
				if (!is_dir($dir))
					mkdir($dir,0755,true);
				$_cache[$name]  =   $value;
				return file_put_contents($filename, self::strip_whitespace("<?php\treturn " . var_export($value, true) . ";?>"));
			}
		}
		if (isset($_cache[$name]))
			return $_cache[$name];
		// 获取缓存数据
		if (is_file($filename)) {
			$value          =   include $filename;
			$_cache[$name]  =   $value;
		} else {
			$value          =   false;
		}
		return $value;
	}

	/**
	 * 去除代码中的空白和注释
	 * @param string $content 代码内容
	 * @return string
	 * @author ChenZhiYin
	 * @version 1.1.0 2014-10-20
	 */
	public static function strip_whitespace($content) {
		$stripStr   = '';
		//分析php源码
		$tokens     = token_get_all($content);
		$last_space = false;
		for ($i = 0, $j = count($tokens); $i < $j; $i++) {
			if (is_string($tokens[$i])) {
				$last_space = false;
				$stripStr  .= $tokens[$i];
			} else {
				switch ($tokens[$i][0]) {
					//过滤各种PHP注释
					case T_COMMENT:
					case T_DOC_COMMENT:
						break;
						//过滤空格
					case T_WHITESPACE:
						if (!$last_space) {
							$stripStr  .= ' ';
							$last_space = true;
						}
						break;
					case T_START_HEREDOC:
						$stripStr .= "<<<THINK\n";
						break;
					case T_END_HEREDOC:
						$stripStr .= "THINK;\n";
						for($k = $i+1; $k < $j; $k++) {
							if(is_string($tokens[$k]) && $tokens[$k] == ';') {
								$i = $k;
								break;
							} else if($tokens[$k][0] == T_CLOSE_TAG) {
								break;
							}
						}
						break;
					default:
						$last_space = false;
					$stripStr  .= $tokens[$i][1];
				}
			}
		}
		return $stripStr;
	}

	/**
	 * 产生随机字串，可用来自动生成密码 默认长度6位 字母和数字混合
	 * @param string $len 长度
	 * @param string $type 字串类型
	 * 0 字母 1 数字 其它 混合
	 * @param string $addChars 额外字符
	 * @return string
	 */
	public static function rand_string($len=6,$type='',$addChars='') {
		$str ='';
		switch($type) {
			case 0:
				$chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.$addChars;
				break;
			case 1:
				$chars= str_repeat('0123456789',3);
				break;
			case 2:
				$chars='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.$addChars;
				break;
			case 3:
				$chars='abcdefghijklmnopqrstuvwxyz'.$addChars;
				break;
			case 4:
				$chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借".$addChars;
				break;
			default :
				// 默认去掉了容易混淆的字符oOLl和数字01，要添加请使用addChars参数
				$chars='ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789'.$addChars;
			break;
		}
		if($len>10 ) {//位数过长重复字符串一定次数
			$chars= $type==1? str_repeat($chars,$len) : str_repeat($chars,5);
		}
		if($type!=4) {
			$chars   =   str_shuffle($chars);
			$str     =   substr($chars,0,$len);
		}else{
			// 中文随机字
			for($i=0;$i<$len;$i++){
				$str.= self::msubstr($chars, floor(mt_rand(0,mb_strlen($chars,'utf-8')-1)),1);
			}
		}
		return $str;
	}

	/**
	 * 字符串截取，支持中文和其他编码
	 * @static
	 * @access public
	 * @param string $str 需要转换的字符串
	 * @param string $start 开始位置
	 * @param string $length 截取长度
	 * @param string $charset 编码格式
	 * @param string $suffix 截断显示字符
	 * @return string
	 */
	public static function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) {
		if(function_exists("mb_substr"))
			$slice = mb_substr($str, $start, $length, $charset);
		elseif(function_exists('iconv_substr')) {
			$slice = iconv_substr($str,$start,$length,$charset);
			if(false === $slice) {
				$slice = '';
			}
		}else{
			$re['utf-8']   = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
			$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
			$re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
			$re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
			preg_match_all($re[$charset], $str, $match);
			$slice = join("",array_slice($match[0], $start, $length));
		}
		return $suffix ? $slice.'...' : $slice;
	}


	//输出安全的html
	public static function safe_html($text, $tags = null) {
		$text	=	trim($text);
		//完全过滤注释
		$text	=	preg_replace('/<!--?.*-->/','',$text);
		//完全过滤动态代码
		$text	=	preg_replace('/<\?|\?'.'>/','',$text);
		//完全过滤js
		$text	=	preg_replace('/<script?.*\/script>/','',$text);

		$text	=	str_replace('[','&#091;',$text);
		$text	=	str_replace(']','&#093;',$text);
		$text	=	str_replace('|','&#124;',$text);
		//过滤换行符
		$text	=	preg_replace('/\r?\n/','',$text);
		//br
		$text	=	preg_replace('/<br(\s\/)?'.'>/i','[br]',$text);
		$text	=	preg_replace('/<p(\s\/)?'.'>/i','[br]',$text);
		$text	=	preg_replace('/(\[br\]\s*){10,}/i','[br]',$text);
		//过滤危险的属性，如：过滤on事件lang js
		while(preg_match('/(<[^><]+)( lang|on|action|background|codebase|dynsrc|lowsrc)[^><]+/i',$text,$mat)){
			$text=str_replace($mat[0],$mat[1],$text);
		}
		while(preg_match('/(<[^><]+)(window\.|javascript:|js:|about:|file:|document\.|vbs:|cookie)([^><]*)/i',$text,$mat)){
			$text=str_replace($mat[0],$mat[1].$mat[3],$text);
		}
		if(empty($tags)) {
			$tags = 'table|td|th|tr|i|b|u|strong|img|p|br|div|strong|em|ul|ol|li|dl|dd|dt|a';
		}
		//允许的HTML标签
		$text	=	preg_replace('/<('.$tags.')( [^><\[\]]*)>/i','[\1\2]',$text);
		$text = preg_replace('/<\/('.$tags.')>/Ui','[/\1]',$text);
		//过滤多余html
		$text	=	preg_replace('/<\/?(html|head|meta|link|base|basefont|body|bgsound|title|style|script|form|iframe|frame|frameset|applet|id|ilayer|layer|name|script|style|xml)[^><]*>/i','',$text);
		//过滤合法的html标签
		while(preg_match('/<([a-z]+)[^><\[\]]*>[^><]*<\/\1>/i',$text,$mat)){
			$text=str_replace($mat[0],str_replace('>',']',str_replace('<','[',$mat[0])),$text);
		}
		//转换引号
		while(preg_match('/(\[[^\[\]]*=\s*)(\"|\')([^\2=\[\]]+)\2([^\[\]]*\])/i',$text,$mat)){
			$text=str_replace($mat[0],$mat[1].'|'.$mat[3].'|'.$mat[4],$text);
		}
		//过滤错误的单个引号
		while(preg_match('/\[[^\[\]]*(\"|\')[^\[\]]*\]/i',$text,$mat)){
			$text=str_replace($mat[0],str_replace($mat[1],'',$mat[0]),$text);
		}
		//转换其它所有不合法的 < >
		$text	=	str_replace('<','&lt;',$text);
		$text	=	str_replace('>','&gt;',$text);
		$text	=	str_replace('"','&quot;',$text);
		//反转换
		$text	=	str_replace('[','<',$text);
		$text	=	str_replace(']','>',$text);
		$text	=	str_replace('|','"',$text);
		//过滤多余空格
		$text	=	str_replace('  ',' ',$text);
		return $text;
	}

	/**
	 * XML编码
	 * @param mixed $data 数据
	 * @param string $root 根节点名
	 * @param string $item 数字索引的子节点名
	 * @param string $attr 根节点属性
	 * @param string $id   数字索引子节点key转换的属性名
	 * @param string $encoding 数据编码
	 * @return string
	 */
	public static function xml_encode($data, $root='think', $item='item', $attr='', $id='id', $encoding='utf-8') {
		if(is_array($attr)){
			$_attr = array();
			foreach ($attr as $key => $value) {
				$_attr[] = "{$key}=\"{$value}\"";
			}
			$attr = implode(' ', $_attr);
		}
		$attr   = trim($attr);
		$attr   = empty($attr) ? '' : " {$attr}";
		$xml    = "<?xml version=\"1.0\" encoding=\"{$encoding}\"?>";
		$xml   .= "<{$root}{$attr}>";
		$xml   .= self::data_to_xml($data, $item, $id);
		$xml   .= "</{$root}>";
		return $xml;
	}

	/**
	 * 数据XML编码
	 * @param mixed  $data 数据
	 * @param string $item 数字索引时的节点名称
	 * @param string $id   数字索引key转换为的属性名
	 * @return string
	 */
	public static function data_to_xml($data, $item='item', $id='id') {
		$xml = $attr = '';
		foreach ($data as $key => $val) {
			if(is_numeric($key)){
				$id && $attr = " {$id}=\"{$key}\"";
				$key  = $item;
			}
			$xml    .=  "<{$key}{$attr}>";
			$xml    .=  (is_array($val) || is_object($val)) ? self::data_to_xml($val, $item, $id) : $val;
			$xml    .=  "</{$key}>";
		}
		return $xml;
	}

	/*
	 * description Url中文转码（编解码）函数
	* @param mixed $source
	* @return string
	*/
	public static function utf8RawUrlDecode ($source)
	{
		$decodedStr = "";
		$pos = 0;
		$len = strlen ($source);
		while ($pos < $len) {
			$charAt = substr ($source, $pos, 1);
			if ($charAt == '%') {
				$pos++;
				$charAt = substr ($source, $pos, 1);
				if ($charAt == 'u') {
					// we got a unicode character
					$pos++;
					$unicodeHexVal = substr ($source, $pos, 4);
					$unicode = hexdec ($unicodeHexVal);
					$entity = "&#". $unicode . ';';
					$decodedStr .= utf8_encode ($entity);
					$pos += 4;
				}
				else {
					// we have an escaped ascii character
					$hexVal = substr ($source, $pos, 2);
					$decodedStr .= chr (hexdec ($hexVal));
					$pos += 2;
				}
			} else {
				$decodedStr .= $charAt;
				$pos++;
			}
		}
		return $decodedStr;
	}

	/**
	 * 使用正则验证数据
	 * @access public
	 * @param string $value  要验证的数据
	 * @param string $rule 验证规则
	 * @return boolean
	 */
	public static function regex_match($value,$rule) {
		$validate = array(
				'require'   =>  '/.+/',
				'email'     =>  '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/',
				'url'       =>  '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/',
				'currency'  =>  '/^\d+(\.\d+)?$/',
				'number'    =>  '/^\d+$/',
				'zip'       =>  '/^\d{6}$/',
				'integer'   =>  '/^[-\+]?\d+$/',
				'double'    =>  '/^[-\+]?\d+(\.\d+)?$/',
				'english'   =>  '/^[A-Za-z]+$/',
		);
		// 检查是否有内置的正则表达式
		if(isset($validate[strtolower($rule)]))
			$rule       =   $validate[strtolower($rule)];
		return preg_match($rule,$value)===1;
	}



	// 自动转换字符集 支持数组转换
	public static function auto_charset($fContents, $from='gbk', $to='utf-8') {
		$from = strtoupper($from) == 'UTF8' ? 'utf-8' : $from;
		$to = strtoupper($to) == 'UTF8' ? 'utf-8' : $to;
		if (strtoupper($from) === strtoupper($to) || empty($fContents) || (is_scalar($fContents) && !is_string($fContents))) {
			//如果编码相同或者非字符串标量则不转换
			return $fContents;
		}
		if (is_string($fContents)) {
			if (function_exists('mb_convert_encoding')) {
				return mb_convert_encoding($fContents, $to, $from);
			} elseif (function_exists('iconv')) {
				return iconv($from, $to, $fContents);
			} else {
				return $fContents;
			}
		} elseif (is_array($fContents)) {
			foreach ($fContents as $key => $val) {
				$_key = self::auto_charset($key, $from, $to);
				$fContents[$_key] = self::auto_charset($val, $from, $to);
				if ($key != $_key)
					unset($fContents[$key]);
			}
			return $fContents;
		}
		else {
			return $fContents;
		}
	}

	/**
	 * 得到$_REQUEST输入参数,过滤+默认值设置,这里不做array_change_key_case,使用此方法前请外部处理一次
	 * @param string|array $param	需获取的$_REQUEST参数, 可以是数组或字符串
	 * @param string|array $filter	过滤方法, 可以是数组或字符串
	 * @param string $def	参数设置默认值
	 * @return Ambigous <string, number>
	 * @author Chen Zhi Yin
	 * @version 1.0 2014-08-18
	 */
	public static function getRequest($param,$filter='trim',$def=''){
		if (empty($filter)){
			$filter='trim';
		}
		$val = '';
		if (!empty($param)){
			if (is_string($param)){
				$param=strtolower($param);
				if ($filter=='intval'){
					$val = isset($_REQUEST[$param])?intval($_REQUEST[$param]):intval($def);
				}else{
					$val=isset($_REQUEST[$param])?$filter($_REQUEST[$param]):$def;
				}
			}elseif (is_array($param)){
				if (is_string($filter)){
					foreach ($param as $p){
						$p=strtolower($p);
						if ($filter=='intval'){
							$val[$p] = isset($_REQUEST[$p])?intval($_REQUEST[$p]):intval($def);
						}else{
							$val[$p]=isset($_REQUEST[$p])?$filter($_REQUEST[$p]):$def;
						}
					}
				}elseif (is_array($filter)){
					foreach ($param as $k=>$p){
						$p=strtolower($p);
						if (isset($filter[$k])){
							if ($filter[$k]=='intval'){
								$val[$p] = isset($_REQUEST[$p])?intval($_REQUEST[$p]):intval($def);
							}else{
								$val[$p]=isset($_REQUEST[$p])?$filter($_REQUEST[$p]):$def;
							}
						}else{
							$val[$p]=isset($_REQUEST[$p])?trim($_REQUEST[$p]):$def;
						}
					}
				}
			}else{
				$param=strtolower($param);
				$val = isset($_REQUEST[$param])?trim($_REQUEST[$param]):$def;
			}
		}
		return $val;
	}

	/*
	 * description 得到URL参数
	* @param int $type (0:默认值REQUEST,1:GET,2:POST)
	* @return string
	*/
	public static function getRequestString($para,$type=0)
	{
		if($type == 0){
			return isset($_REQUEST[$para]) ? $_REQUEST[$para] : "";
		}else if($type == 1){
			return isset($_GET[$para]) ? $_GET[$para] : "";
		}else if($type == 2){
			return isset($_POST[$para]) ? $_POST[$para] : "";
		}else{
			return "";
		}
	}


	/*
	 * description 得到URL整形参数
	* @param int $type (0:默认值REQUEST,1:GET,2:POST)
	* @return string
	*/
	public static function getRequestInt($para,$type=0) {
		$reqStr =  self::getRequestString($para,$type);
		$result = 0;
		self::intParse($reqStr,$result);
		return $result;
	}

	/*
	 * description 判断字符串是否为整形,并返回转化后的结果$result
	* @param mixed $input
	* @param mixed $result
	* @return bool
	*/
	public static function intParse($input,&$result)
	{
		$result = 0;

		if(trim($input) == "0")
		{
			return true;
		}

		if(empty($input)){
			return false;
		}
		if(!preg_match("/^-?\d+$/",$input)){
			return false;
		}
		$val = doubleval($input);
		if($val>PHP_MAX_INT || $val < PHP_MIN_INT){
			return false;
		}
		$result = intval($input);
		return true;
	}



	/**
	 * description 检查请求是否允许访问
	 *
	 * @param mixed $host     来源域名
	 * @param mixed $iplist   IP列表
	 * @param mixed $type     IP列表类型，0：白名单，1：黑名单
	 */
	public static function isAccess($host="bbbtgo.com",$iplist=null, $type=0)
	{

		if(!empty($host))
		{
			if(!isset($_SERVER["HTTP_REFERER"]))
			{
				return false;
			}

			$refe = $_SERVER["HTTP_REFERER"];

			if(stripos($refe,$host)===false)
			{
				return false;
			}
		}

		if(!empty($iplist) && is_array($iplist))
		{
			$userip = self::getUserIP();
			//echo $userip;
			if($type === 0) //白名单
			{
				return  in_array($userip,$iplist,true) ;
			}
			else
			{
				return  !in_array($userip,$iplist,true) ;
			}
		}

		return true;
	}


	/**
	 * URL跳转
	 *
	 * @param mixed $url     跳转URL
	 * @param mixed $msg     跳转前提示信息
	 * @param mixed $istop   是否使用top.location 默认 false
	 */
	public static function redirect($url,$msg='',$istop=false) {
		if(empty($msg)) {
			header("Location:{$url}");
		}else {
			$response = "<script>alert('{$msg}');". ( $istop ? 'top.' : '' ) . "location.href='{$url}';</script>";
			echo $response;
		}

		exit();
	}


	/**
	 * 获取某个Cookie值
	 * @static
	 * @access public
	 * @param string $name
	 * @return mixed
	 */
	public static function getCookie($name) {
		if(isset($_COOKIE[$name])){
			$value = $_COOKIE[$name];

			return $value;
		}
		return null;
	}

	/**
	 * 设置某个Cookie值
	 * @static
	 * @access public
	 * @param string $name
	 * @param mixed $value
	 * @param int $expire
	 * @param string $path
	 * @param string $domain
	 */
	public static function setCookie($name, $value, $expire='', $path='/', $domain='') {
		$expire = !empty($expire) ? time() + $expire : 0;

		setcookie($name, $value, $expire, $path, $domain);
		$_COOKIE[$name] = $value;
	}

	/**
	 * 得到用户IP
	 *
	 */
	public static function getUserIP()
	{
		$realIP = FALSE;
		if(!empty($_SERVER['HTTP_CLIENT_IP'])) {
			$realIP = $_SERVER['HTTP_CLIENT_IP'];
		}elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
			$ips = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
			foreach($ips as $ip) {
				$ip = trim($ip);
				if(!self::isLAN($ip)) {//非局域网
					$realIP = $ip;
					break;
				}
			}
		}else {
			$realIP = $_SERVER['REMOTE_ADDR'];
		}
		return $realIP ? $realIP : 'unknow IP';
	}
	/**
	 * 是否为局域网IP
	 * ip地址中预留的内网ip地址如下：
	 * A类： 10.0.0.0 - 10.255.255.255
	 * B类： 172.16.0.0 - 172.31.255.255
	 * C类： 192.168.0.0 - 192.168.255.255
	 * @param string $ip
	 */
	public static function isLAN($ip)
	{
		$privite = array(
				'A' =>array(
						'start'=>'10.0.0.0',
						'end'  =>'10.255.255.255'
				),
				'B' =>array(
						'start'=>'172.16.0.0',
						'end'  =>'172.31.255.255'
				),
				'C' =>array(
						'start'=>'192.168.0.0',
						'end'  =>'192.168.255.255'
				)
		);
		$isPrivate = FALSE;
		$lip       = sprintf('%u',ip2long($ip));
		foreach($privite as $segment) {
			$lstart = sprintf('%u',ip2long($segment['start']));
			$lend   = sprintf('%u',ip2long($segment['end']));

			if($lstart <= $lip && $lip <= $lend) {//在局域网区间
				$isPrivate = TRUE;
				break;
			}
		}
		return $isPrivate;
	}

	/**
	 *
	 * 把对象转成数组
	 * @param $object 要转的对象$object
	 */
	public static function object_to_array($obj) {
		$_arr = is_object($obj) ? get_object_vars($obj) : $obj;

		if($_arr){
			foreach ($_arr as $key => $val) {
				$val = (is_array($val) || is_object($val)) ? self::object_to_array($val) : $val;
				$arr[$key] = $val;
			}

			return $arr;
		}
		return $_arr;

	}
	/**
	 * 获取当前请求的URL
	 */
	public static function getCurrentUrl()
	{
		$url='http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
		return $url;
	}
	/*
	 *验证是否邮箱地址
	*/
	public static function checkIsEmail($mail)
	{
		return preg_match('/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/',$mail);
	}

	//php获取中文字符拼音首字母
	public static function getFirstCharter($str){
		if(empty($str)){
			return '';
		}
		//首字符
		$fchar=ord($str{0});

		if($fchar>=ord('A')&&$fchar<=ord('z')) {
			return strtoupper($str{0});
		}

		$s1 = iconv("UTF-8","GBK", $str);

		$s2 = iconv("GBK","UTF-8", $s1);

		$s=$s2==$str?$s1:$str;

		$asc=ord($s{0})*256+ord($s{1})-65536;

		if($asc>=-20319&&$asc<=-20284) return 'A';
		if($asc>=-20283&&$asc<=-19776) return 'B';
		if($asc>=-19775&&$asc<=-19219) return 'C';
		if($asc>=-19218&&$asc<=-18711) return 'D';
		if($asc>=-18710&&$asc<=-18527) return 'E';
		if($asc>=-18526&&$asc<=-18240) return 'F';
		if($asc>=-18239&&$asc<=-17923) return 'G';
		if($asc>=-17922&&$asc<=-17418) return 'H';
		if($asc>=-17417&&$asc<=-16475) return 'J';
		if($asc>=-16474&&$asc<=-16213) return 'K';
		if($asc>=-16212&&$asc<=-15641) return 'L';
		if($asc>=-15640&&$asc<=-15166) return 'M';
		if($asc>=-15165&&$asc<=-14923) return 'N';
		if($asc>=-14922&&$asc<=-14915) return 'O';
		if($asc>=-14914&&$asc<=-14631) return 'P';
		if($asc>=-14630&&$asc<=-14150) return 'Q';
		if($asc>=-14149&&$asc<=-14091) return 'R';
		if($asc>=-14090&&$asc<=-13319) return 'S';
		if($asc>=-13318&&$asc<=-12839) return 'T';
		if($asc>=-12838&&$asc<=-12557) return 'W';
		if($asc>=-12556&&$asc<=-11848) return 'X';
		if($asc>=-11847&&$asc<=-11056) return 'Y';
		if($asc>=-11055&&$asc<=-10247) return 'Z';
		return substr($str,0,1);
	}
	/*Des 跨月计算
	 *@param date $stime  开始时间
	*@param date $etime  结束时间
	*return int 0不跨月1跨一个月2跨两个月
	*/
	static function getMonthByDate($stime,$etime)
	{
		if(empty($stime) || empty($etime)){
			return false;
		}
		$sMonth = explode('-',$stime);
		$eMonth = explode('-',$etime);
		if($sMonth[0] != $eMonth[0]){//如果是跨年
			$diffNum = ($eMonth[1] +12 )- $sMonth[1];
		}else{
			$diffNum = $eMonth[1] - $sMonth[1];
		}
		return $diffNum;
	}
	/*Des 中间月计算
	 *@param date $stime  开始时间
	*@param date $etime  结束时间
	*/
	static function getMiddleMonth($stime,$etime)
	{
		if(empty($stime) || empty($etime)){
			return false;
		}
		$sMonth = explode('-',$stime);
		$eMonth = explode('-',$etime);
		if($sMonth[0] != $eMonth[0]){//如果是跨年则 开始时间有两种月份11、12 结束时间有01、02月
			if($sMonth[1]==11 && $eMonth[1]==01){
				$midMonth = $sMonth[0] . 12;
			}else{
				$midMonth = $eMonth[0] . 02;
			}
		}else{
			$midMonth = $eMonth[0] . ($eMonth[1]-1);
		}
		return $midMonth;
	}
	/*Des 二维数组去重
	 *@param $ar 二维数组
	*@param arr $filter  二维数组键值数组(根据二维数组键值去重，如果为空则按所有二维数组键值去重)
	*@auther derek
	*@date 20140227
	*/
	static function array_multi_unique($ar, $filter = array()) {
		if (! empty ( $filter )) {
			$_v = array_fill_keys ( $filter, ' ' );
			$_ar = array ();
			foreach ( $ar as $k => $v ) {
				$_ar [$k] = array_intersect_key ( $v, $_v );
			}
		} else {
			$_ar = $ar;
		}

		$_ar = array_map ( 'serialize', $_ar );
		$_ar = array_unique ( $_ar );
		$_ar = array_map ( 'unserialize', $_ar );

		if (! empty ( $filter )) {
			return array_intersect_key ( $ar, $_ar );
		} else {
			return $_ar;
		}
	}



	/**
	 * 通过HTTP GET 请求数据
	 *
	 * @param mixed $url       请求URL
	 * @param mixed $timeout   超时时间,默认5秒
	 * @param mixed $encoding  编码
	 * @return array("status" => ture|false,"data" =>"","err"=> "","http_status"=>200);
	 */
	public static function curl_http_get_contents($url,$timeout=5,$encoding="")
	{

		$result = array(
				"status" => false,
				"http_status" => 0,
				"data" => "",
				"err"=> ""
		);

		try{
			$ch = curl_init();
			//模拟用户使用的浏览器
			curl_setopt( $ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1" );
			curl_setopt( $ch, CURLOPT_URL, $url );                //要访问的地址
			//curl_setopt( $ch, CURLOPT_COOKIEJAR, $cookie );     //存放Cookie信息的文件名称
			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);       //使用自动跳转
			curl_setopt($ch, CURLOPT_ENCODING, $encoding);        //编码
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);       //获取的信息以文件流的形式返回
			curl_setopt($ch, CURLOPT_AUTOREFERER, true);          //自动设置Referer
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);      //对认证证书来源的检查
			curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);          //设置超时限制
			curl_setopt($ch, CURLOPT_MAXREDIRS, 10);              //指定最多的HTTP重定向的数量
			$contents = curl_exec($ch);
			$response = curl_getinfo($ch);
			$result["status"] = true;
			$result["http_status"] = $response["http_code"];
			$result["data"] = $contents;
			if(curl_errno($ch)) //出错
			{
				$result["err"] = curl_error($ch);
			}
			curl_close ($ch);

		}
		catch(Exception $ex)
		{
			$result["status"] = false;
			$result["err"] = $ex;
		}

		return $result;

	}


	/**
	 * 通过HTTP POST 请求数据
	 *
	 * @param mixed $url       请求URL
	 * @param mixed $timeout   超时时间,默认5秒
	 * @param mixed $encoding  编码
	 * @return array("status" => ture|false,"data" =>"","err"=> "","http_status"=>200);
	 */
	public static function curl_http_post_contents($url,$data,$timeout=5,$encoding="")
	{
		$result = array(
				"status" => false,
				"http_status" => 0,
				"data" => "",
				"err"=> ""
		);


		try {
			$ch = curl_init();
			//模拟用户使用的浏览器
			curl_setopt( $ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1" );
			curl_setopt( $ch, CURLOPT_URL, $url );                //要访问的地址
			//curl_setopt( $ch, CURLOPT_COOKIEJAR, $cookie );     //存放Cookie信息的文件名称
			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);       //使用自动跳转
			curl_setopt($ch, CURLOPT_ENCODING, $encoding);        //编码
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);       //获取的信息以文件流的形式返回
			curl_setopt($ch, CURLOPT_AUTOREFERER, true);          //自动设置Referer
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);      //对认证证书来源的检查
			curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);          //设置超时限制
			curl_setopt($ch, CURLOPT_MAXREDIRS, 10);              //指定最多的HTTP重定向的数量
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
			$contents = curl_exec($ch);
			$response = curl_getinfo($ch);
			$result["status"] = true;
			$result["http_status"] = $response["http_code"];
			$result["data"] = $contents;
			if(curl_errno($ch)) //出错
			{
				$result["err"] = curl_error($ch);
			}
			curl_close ($ch);

		}catch(Exception $ex) {
			$result["status"] = false;
			$result["err"] = "";
		}

		return $result;

	}

	/**
	 * 根据数组中的某个键值大小进行排序，仅支持二维数组
	 *
	 * @param array $array 排序数组
	 * @param string $key 键值
	 * @param bool $asc 默认正序
	 * @return array 排序后数组
	 */
	static function  arraySortByKey(array $array, $key, $asc = true) {
		$result = array();
		if(is_array($array) && count($array)>0){
			// 整理出准备排序的数组
			foreach ( $array as $k => &$v ) {
				$values[$k] = isset($v[$key]) ? $v[$key] : '';
			}
			unset($v);
			// 对需要排序键值进行排序
			$asc ? asort($values) : arsort($values);
			// 重新排列原有数组
			foreach ( $values as $k => $v ) {
				$result[$k] = $array[$k];
			}
		}
		return $result;
	}
	/**
	 * 根据数组中的某个键值大小进行排序，仅支持三维数组
	 *
	 * @param array $array 排序数组
	 * @param string $keys 键值
	 * @param bool $asc 默认正序
	 * @return array 排序后数组
	 */
	function arraysort3weiByKey(array $array, $keys, $asc = true){
		foreach($array as $key=>$val){
			$new_array= array();
			$sort_array = array();
			foreach($val as $k=>$v){
				$sort_array[$k] = $v[$keys];
			}
			// 对需要排序键值进行排序
			$asc ? asort($sort_array) : arsort($sort_array);
			reset($sort_array);

			foreach($sort_array as $k=>$v){
				$new_array[$k] = $array[$key][$k];
			}
			$array[$key] = $new_array;
		}
		return $array;
	}

    /**
     * @param $input 二维数组
     * @param $key 指定一维索引值
     * @param array $twoindex 二维数组(键为自定义，值为二维数组的键)
     * @return array 二维数组
     */
    public static function arrayToMaps($input,$key,$twoindex=array()){
        if(empty($input) || !is_array($input)){
            return $input;
        }
        $tmp_array = array();
        foreach ($input as $v){
            if(empty($v[$key])){
                return $input;
            }
            foreach ($twoindex as $kk=>$vv){
                $tmp_array[$v[$key]][$kk] = $v[$vv];
            }
        }
        return $tmp_array;
    }

    /**
     * @param $num
     * @return string
     * @desc:字节转换
     */
    public static function getFilesize($num){
        $p = 0;
        if($num>=1024 && $num<pow(1024, 2)){
            $p = 1;
            $format = 'Kb';
        }
        if ($num>=pow(1024, 2) && $num<pow(1024, 3)) {
            $p = 2;
            $format = 'M';
        }
        if ($num>=pow(1024, 3) && $num<pow(1024, 4)) {
            $p = 3;
            $format = 'G';
        }
        if ($num>=pow(1024, 4) && $num<pow(1024, 5)) {
            $p = 3;
            $format = 'T';
        }
        $num /= pow(1024, $p);
        return number_format($num, 1).' '.$format;
    }
}